home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / LISP Related / U. Mass AI & LISP Tools / MODULES / RULES / RULE-Demo.lisp < prev    next >
Encoding:
Text File  |  1990-06-25  |  15.8 KB  |  377 lines  |  [TEXT/CCL ]

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ; File:         Rule-Demo.lisp
  3. ; Author:       Dan Suthers
  4. ; Created:      21-Mar-89 13:21:00
  5. ; Modified:     24-Jun-90 23:14:36 (Dan Suthers)
  6. ; Language:     Common Lisp
  7. ; Package:      USER
  8. ;
  9. ; Description:  Some examples to run rules on.  I've thrown together two
  10. ;               examples which I used for testing: reasoning about values 
  11. ;               in an electric circuit, and reasoning about relationships.
  12. ;               This demos mainly the backchainer.
  13. ;
  14. ;               Note that some of these examples show problems with the 
  15. ;               backchainer, in particular redundant reasoning.  I included
  16. ;               these to help you evaluate the limitations of this package.
  17. ;               You should evalute the database and rule defining sections
  18. ;               as a group, but evaluate the individual rule invocations 
  19. ;               and graphing expressions one at a time to see what 
  20. ;               happens.  Use the graphical interface (clicking on nodes)
  21. ;               to examine the support tree, and the SM Browser to look 
  22. ;               at the rules.
  23. ;               
  24. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  25.  
  26. (in-package "USER")
  27.  
  28. (defun DEMO-GRAPH-SUPPORT-TREE (root-node)
  29.   (ccl:oneof grapher:*graph-window*
  30.              :window-title    (rule::label-string (rule::trj-node-claim root-node) 10 40)
  31.              :window-size     (ccl:make-point (- *screen-width* 4) 280)
  32.              :window-position (ccl:make-point 2 ccl:*menubar-bottom*)
  33.              :graph-view
  34.              (rule::trj-node->graph-view root-node
  35.                                          :vertical-tree
  36.                                          :as-found
  37.                                          6
  38.                                          nil)))
  39.  
  40. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  41. ;;;                 CIRCUITS: Forward and Back Chaining
  42. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  43. ;;; Representation of a circuit in a DNET database.  Evaluate all of this
  44. ;;; section as a group. Note here I use lower level DNET building functions 
  45. ;;; instead of MAKE-DATA-BASE and ADD-DATUM.
  46.  
  47. ;;; dnet:make-dnet is what rule:make-data-base calls (virtually identical).
  48.  
  49. (dnet:make-dnet ':CIRCUIT-1 
  50.   :indexpr-hook 'NIL
  51.   :delexpr-hook 'NIL
  52.   :info 'NIL)
  53.  
  54. (dnet:indexpr '(PORTS (BATTERY B1) (PORT PB1-1) (PORT PB1-2)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  55. (dnet:indexpr '(PORTS (RESISTOR R1) (PORT PR1-1) (PORT PR1-2)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  56. (dnet:indexpr '(PORTS (LIGHT L1) (PORT PL1-1) (PORT PL1-2)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  57. (dnet:indexpr '(PORTS (LIGHT L2) (PORT PL2-1) (PORT PL2-2)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  58. (dnet:indexpr '(VOLTAGE (BATTERY B1) (VOLTS 6)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  59. (dnet:indexpr '(RESISTANCE (RESISTOR R1) (OHMS 10)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  60. (dnet:indexpr '(RESISTANCE (LIGHT L1) (OHMS 2)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  61. (dnet:indexpr '(RESISTANCE (LIGHT L2) (OHMS 2)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  62. (dnet:indexpr '(WIRE (PORT PB1-1) (PORT PL1-1)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  63. (dnet:indexpr '(WIRE (PORT PB1-2) (PORT PL1-2)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  64. (dnet:indexpr '(WIRE (PORT PL1-1) (PORT PR1-1)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  65. (dnet:indexpr '(WIRE (PORT PL1-2) (PORT PL2-2)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  66. (dnet:indexpr '(WIRE (PORT PR1-2) (PORT PL2-1)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807247882)))
  67. (dnet:indexpr '(EFFICIENCY (LIGHT L2) (RATIO 2/3)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807249648)))
  68. (dnet:indexpr '(EFFICIENCY (LIGHT L1) (RATIO 2/3)) ':CIRCUIT-1 '(#S(RULE:JUSTIFICATION RULE::WARRANT :DATUM RULE::GROUNDS NIL TIME 2807249626)))
  69.  
  70. ;;; Get a bunch of variables out of the way ...
  71. (rule:DEFVARIABLES "A" "ATTRIBUTE" "C1" "C2" "CTYPE1" "CTYPE2" 
  72.                    "D" "DEV" "E" "INSTANCE1" "INSTANCE2" "L" 
  73.                    "LUM" "NEG-V" "OBJECT-TYPE" "P1" "P2" "P3" 
  74.                    "P4" "R" "R1" "R2" "SCALE" "V" "V1" "V2" "VALUE-TYPE")
  75.  
  76. (rule:rule BRIGHTNESS
  77.  :ANTECEDENT        
  78.  (:seq (ports (light ?:l) (port ?:p1) (port ?:p2))
  79.       (efficiency (light ?:l) (ratio ?:e))
  80.       (current (port ?:p1) (port ?:p2) (amps ?:a))
  81.       (:bind ?:lum (* ?:e ?:a)))
  82.  :CONSEQUENT        (brightness (light ?:l) (lumens ?:lum))
  83.  :DIRECTIONS        :backward
  84.  :INTERNED-IN       (:network-rules)
  85.  :INFO              ((:domain . :networks))
  86.  :COMMENTS          "Says how to find the brightness of a light as a function of current.")
  87.  
  88. (rule:rule OHMS-LAW-FOR-CURRENT
  89.  :ANTECEDENT        
  90.  (:seq (resistance (port ?:p1) (port ?:p2) (ohms ?:r))
  91.       (voltage (port ?:p1) (port ?:p2) (volts ?:v))
  92.       (:bind ?:a (/ ?:v ?:r)))
  93.  :CONSEQUENT        (current (port ?:p1) (port ?:p2) (amps ?:a))
  94.  :DIRECTIONS        :backward
  95.  :INTERNED-IN       (:network-rules)
  96.  :INFO              ((:domain . :networks))
  97.  :COMMENTS          "Given resistance and voltage across ports, provides current flow.")
  98.  
  99. (rule:rule PROPORTION
  100.  :ANTECEDENT        
  101.  (:seq (?:attribute (?:object-type ?:instance1) (?:value-type ?:v1))
  102.       (?:attribute (?:object-type ?:instance2) (?:value-type ?:v2))
  103.       (:bind ?:r (/ ?:v1 ?:v2)))
  104.  :CONSEQUENT        
  105.  (proportion (?:attribute (?:object-type ?:instance1))
  106.                   (?:attribute (?:object-type ?:instance2))
  107.                   (ratio ?:r))
  108.  :DIRECTIONS        :backward
  109.  :INTERNED-IN       (:network-rules)
  110.  :INFO              ((:domain . :networks))
  111.  :COMMENTS          "Says how to find the proportion between two attributes.")
  112.  
  113. (rule:rule RESISTANCE-ACROSS-DEVICE-PORTS
  114.  :ANTECEDENT        
  115.  (:and (ports (?:dev ?:d) (port ?:p1) (port ?:p2))
  116.       (resistance (?:dev ?:d) (?:scale ?:r)))
  117.  :CONSEQUENT        
  118.  (:and (resistance (port ?:p1) (port ?:p2) (?:scale ?:r))
  119.       (resistance (port ?:p2) (port ?:p1) (?:scale ?:r)))
  120.  :DIRECTIONS        :forward
  121.  :INTERNED-IN       (:network-rules)
  122.  :INFO              ((:domain . :networks))
  123.  :COMMENTS          "Assigns the resistance of a device to its ports.")
  124.  
  125. (rule:rule SERIES-CURRENT
  126.  :ANTECEDENT        
  127.  (:and
  128.  (series-network (port ?:p1)
  129.                        (port ?:p2)
  130.                        (port ?:p3)
  131.                        (port ?:p4))
  132.  (current (port ?:p1) (port ?:p4) (?:scale ?:a)))
  133.  :CONSEQUENT        (current (port ?:p3) (port ?:p4) (?:scale ?:a))
  134.  :DIRECTIONS        :backward
  135.  :INTERNED-IN       (:network-rules)
  136.  :INFO              nil
  137.  :COMMENTS          
  138.  "Says that the current across an entire series network is 
  139. also the current across subcomponents.")
  140.  
  141. (rule:rule SERIES-NETWORK
  142.  :ANTECEDENT        
  143.  (:and (ports (?:ctype1 ?:c1) (port ?:p1) (port ?:p2))
  144.       (ports (?:ctype2 ?:c2) (port ?:p3) (port ?:p4))
  145.       (wire (port ?:p2) (port ?:p3)))
  146.  :CONSEQUENT        
  147.  (:and
  148.  (series-network (port ?:p1)
  149.                        (port ?:p2)
  150.                        (port ?:p3)
  151.                        (port ?:p4))
  152.  (series-network (port ?:p4)
  153.                        (port ?:p3)
  154.                        (port ?:p2)
  155.                        (port ?:p1)))
  156.  :DIRECTIONS        :backward
  157.  :INTERNED-IN       (:network-rules)
  158.  :INFO              nil
  159.  :COMMENTS          "Defines simple series networks.")
  160.  
  161. (rule:rule SERIES-RESISTANCE
  162.  :ANTECEDENT        
  163.  (:seq
  164.  (series-network (port ?:p1)
  165.                        (port ?:p2)
  166.                        (port ?:p3)
  167.                        (port ?:p4))
  168.  (resistance (port ?:p1) (port ?:p2) (?:scale ?:r1))
  169.  (resistance (port ?:p3) (port ?:p4) (?:scale ?:r2))
  170.  (:bind ?:r (+ ?:r1 ?:r2)))
  171.  :CONSEQUENT        (resistance (port ?:p1) (port ?:p4) (?:scale ?:r))
  172.  :DIRECTIONS        :backward
  173.  :INTERNED-IN       (:network-rules)
  174.  :INFO              nil
  175.  :COMMENTS          "Finds the resistance of a series network by adding the resistance of the componenets.")
  176.  
  177. (rule:rule VOLTAGE-ACROSS-DEVICE-PORTS
  178.  :ANTECEDENT        
  179.  (:and (ports (?:dev ?:d) (port ?:p1) (port ?:p2))
  180.       (voltage (?:dev ?:d) (?:scale ?:v)))
  181.  :CONSEQUENT        
  182.  (:and (voltage (port ?:p1) (port ?:p2) (?:scale ?:v))
  183.       (voltage (port ?:p2) (port ?:p1) (?:scale (:lisp (- ?:v)))))
  184.  :DIRECTIONS        :forward
  185.  :INTERNED-IN       (:network-rules)
  186.  :INFO              ((:domain . :networks))
  187.  :COMMENTS          "Assigns the electromotive voltage to the ports of a device.")
  188.  
  189. (rule:rule VOLTAGE-PROPAGATION
  190.  :ANTECEDENT        
  191.  (:and (wire (port ?:p1) (port ?:p3))
  192.       (wire (port ?:p2) (port ?:p4))
  193.       (voltage (port ?:p1) (port ?:p2) (?:scale ?:v)))
  194.  :CONSEQUENT        (voltage (port ?:p3) (port ?:p4) (?:scale ?:v))
  195.  :DIRECTIONS        :backward
  196.  :INTERNED-IN       (:network-rules)
  197.  :INFO              ((:domain . :networks))
  198.  :COMMENTS          
  199.  "Propagate voltage to directly connected terminals. Voltage conjunct
  200. of antecedent must be last to prevent circularity.")
  201.  
  202. (rule:rule VOLTAGE-PROPAGATION-FLIP-SIGN
  203.  :ANTECEDENT        
  204.  (:seq (voltage-across (port ?:p1) (port ?:p2) (volts ?:v))
  205.       (connected (port ?:p1) (port ?:p3))
  206.       (connected (port ?:p2) (port ?:p4))
  207.       (:bind ?:neg-v (- ?:v)))
  208.  :CONSEQUENT        (voltage-across (port ?:p4) (port ?:p3) (volts ?:neg-v))
  209.  :DIRECTIONS        :backward
  210.  :INTERNED-IN       (:network-rules)
  211.  :INFO              ((:domain . :networks))
  212.  :COMMENTS          "Propagate voltage to directly connected terminals, where voltage must be negated.")
  213.  
  214. (dnet:make-dnet :network-rules)
  215. (rule:add-all-rules)
  216.  
  217. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  218. ;;; CIRCUIT REASONING - evaluate each form one at a time.
  219. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  220.  
  221. ;;; Turn rule trace on if you wish. Then evaluate these ...
  222.  
  223. ;;; Do forward chaining to get some simple facts.
  224.  
  225. (rule:forward-chain :circuit-1 :network-rules)
  226.  
  227. ;;; Simple retrieval of something got by forward chaining -- compare datum just.
  228.  
  229. (rule:support '(voltage (port pb1-1) (port pb1-2) (volts ?:v)) 
  230.               :circuit-1 :network-rules :include-datum-justification nil)
  231. (demo-graph-support-tree rule:*support-tree*)
  232.  
  233. (rule:support '(voltage (port pb1-1) (port pb1-2) (volts ?:v)) 
  234.               :circuit-1 :network-rules :include-datum-justification t)
  235. (demo-graph-support-tree rule:*support-tree*)
  236.  
  237. ;;; Something that takes application of one voltage propagation rule.
  238.  
  239. (rule:support '(voltage (port pl1-1) (port pl1-2) (volts ?:v))
  240.               :circuit-1 :network-rules)
  241. (demo-graph-support-tree rule:*support-tree*)
  242.  
  243. ;;; This requires problem solving across resistor to get voltage.
  244. ;;; Makes a rather complex graph.
  245.  
  246. (dnet:defvariable "LUM")
  247. (rule:support '(brightness (light l1) (lumens ?:lum))
  248.               :circuit-1 :network-rules :record-failure nil)
  249. (demo-graph-support-tree rule:*support-tree*)
  250.  
  251. ;;; A harder test, this takes work to get past the resistor.
  252.  
  253. (rule:support '(brightness (light l2) (lumens ?:lum))
  254.               :circuit-1 :network-rules :record-failure nil)
  255. (demo-graph-support-tree rule:*support-tree*)
  256.  
  257. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  258. ;;; MORE TESTS - Taken from Eriksson & Johannason AAAI-85.
  259. ;;; This part of the demo shows some problems with this backchainer.
  260. ;;; It does redundant reasoning, and needs a TMS to prevent this.
  261. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  262. ;;;; The database of facts.  Evaluate as a group.
  263.  
  264. (dnet:make-dnet ':EE-DB
  265.   :indexpr-hook 'NIL
  266.   :delexpr-hook 'NIL
  267.   :info 'NIL)
  268.  
  269. ;;;                   John                 
  270. ;;;                   /   \                
  271. ;;;                  f     f               
  272. ;;;                 /       \              
  273. ;;;               Ada       Per            
  274. ;;;                        /   \           
  275. ;;;                       f     f          
  276. ;;;                      /       \         
  277. ;;;                     Eva      Pia       
  278. ;;;                      |        |        
  279. ;;;                      m        m        
  280. ;;;                      |        |        
  281. ;;;                     Tom      Tim       
  282.    
  283. (dnet:indexpr '(FATHER ADA JOHN) ':EE-DB '(#S(RULE:JUSTIFICATION RULE::WARRANT :ASSERTED RULE::GROUNDS :DAN-SAYS-SO TIME 2808797026)))
  284. (dnet:indexpr '(FATHER PER JOHN) ':EE-DB '(#S(RULE:JUSTIFICATION RULE::WARRANT :ASSERTED RULE::GROUNDS :DAN-SAYS-SO TIME 2808797032)))
  285. (dnet:indexpr '(FATHER PIA PER) ':EE-DB '(#S(RULE:JUSTIFICATION RULE::WARRANT :ASSERTED RULE::GROUNDS :DAN-SAYS-SO TIME 2808797040)))
  286. (dnet:indexpr '(FATHER EVA PER) ':EE-DB '(#S(RULE:JUSTIFICATION RULE::WARRANT :ASSERTED RULE::GROUNDS :DAN-SAYS-SO TIME 2808797048)))
  287. (dnet:indexpr '(MOTHER TOM EVA) ':EE-DB '(#S(RULE:JUSTIFICATION RULE::WARRANT :ASSERTED RULE::GROUNDS :DAN-SAYS-SO TIME 2808797062)))
  288. (dnet:indexpr '(MOTHER TIM PIA) ':EE-DB '(#S(RULE:JUSTIFICATION RULE::WARRANT :ASSERTED RULE::GROUNDS :DAN-SAYS-SO TIME 2808797070)))
  289.  
  290. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  291. ;;; Rules
  292.  
  293. (dnet:make-dnet :ee-rb)
  294.  
  295. (rule:defvariables "X" "Y" "Z")
  296.  
  297. (rule:rule RULE-1
  298.  :ANTECEDENT        (father ?:x ?:y)
  299.  :CONSEQUENT        (parent ?:x ?:y)
  300.  :DIRECTIONS        :both
  301.  :INTERNED-IN       (:ee-rb)
  302.  :INFO              nil
  303.  :COMMENTS          "Your father is your parent.")
  304. (rule:add-rule 'rule-1 :ee-rb)
  305.  
  306. (rule:rule RULE-2
  307.  :ANTECEDENT        (mother ?:x ?:y)
  308.  :CONSEQUENT        (parent ?:x ?:y)
  309.  :DIRECTIONS        :both
  310.  :INTERNED-IN       (:ee-rb)
  311.  :INFO              nil
  312.  :COMMENTS          "Your mother is your parent.")
  313. (rule:add-rule 'rule-2 :ee-rb)
  314.  
  315. (rule:rule RULE-3
  316.  :ANTECEDENT        (parent ?:x ?:y)
  317.  :CONSEQUENT        (ancestor ?:x ?:y)
  318.  :DIRECTIONS        :both
  319.  :INTERNED-IN       (:ee-rb)
  320.  :INFO              nil
  321.  :COMMENTS          "Your parent is an ancestor.")
  322. (rule:add-rule 'rule-3 :ee-rb)
  323.  
  324. (rule:rule RULE-4
  325.  :ANTECEDENT        (:and (parent ?:x ?:z) (ancestor ?:z ?:y))
  326.  :CONSEQUENT        (ancestor ?:x ?:y)
  327.  :DIRECTIONS        :both
  328.  :INTERNED-IN       (:ee-rb)
  329.  :INFO              nil
  330.  :COMMENTS          "A parent of an ancestor is also an ancestor.")
  331. (rule:add-rule 'rule-4 :ee-rb)
  332.  
  333. (rule:rule RULE-5
  334.  :ANTECEDENT        (ancestor ?:x ?:y)
  335.  :CONSEQUENT        (related ?:x ?:y)
  336.  :DIRECTIONS        :both
  337.  :INTERNED-IN       (:ee-rb)
  338.  :INFO              nil
  339.  :COMMENTS          "You are related to your ancestor.")
  340. (rule:add-rule 'rule-5 :ee-rb)
  341.  
  342. (rule:rule RULE-6
  343.  :ANTECEDENT        (:and (ancestor ?:x ?:z) (ancestor ?:y ?:z))
  344.  :CONSEQUENT        (related ?:x ?:y)
  345.  :DIRECTIONS        :both
  346.  :INTERNED-IN       (:ee-rb)
  347.  :INFO              nil
  348.  :COMMENTS          "You are related to anyone with a common ancestor.")
  349. (rule:add-rule 'rule-6 :ee-rb)
  350.  
  351. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  352. ;;; Tests.
  353.  
  354. ;;; (trace rule:retrieve rule::retrieve-bindings rule::retrieve-backchain 
  355. ;;;        rule::retrieve-and rule::retrieve-or)
  356.  
  357. ;;; Simple.
  358.  
  359. (rule:retrieve '(father ?:x john) :ee-db :ee-rb)
  360.  
  361. (rule:support '(father ?:x john) :ee-db :ee-rb)
  362. (demo-graph-support-tree rule:*support-tree*)
  363.  
  364. (rule:retrieve '(ancestor ?:x per) :ee-db :ee-rb)
  365.  
  366. (rule:support '(ancestor ?:x per) :ee-db :ee-rb)
  367. (demo-graph-support-tree rule:*support-tree*)
  368.  
  369. ;;; This can take a while.
  370.  
  371. (rule:support '(related ada ?:x) :ee-db :ee-rb)
  372. (demo-graph-support-tree rule:*support-tree*)
  373.  
  374. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  375. ;;; EOF
  376.